#ifndef SIMULATION_CORE_GCC_H
#define SIMULATION_CORE_GCC_H

#include <SimulationCore/Core.h>
#include <vector>
namespace SimulationCore
{
    class GDC;
    class GCC
    {
        public:
        GCC()
        :m_x(0),m_y(0),m_z(0)
        {
            
        }

        GCC(double x, double y)
        :m_x(x),m_y(y),m_z(0)
        {
            
        }


        GCC(double x, double y,double z)
        :m_x(x),m_y(y),m_z(y){}


        GCC operator+(const GCC& gcc) const
        {
            return GCC(m_x+gcc.m_x,m_y+gcc.m_y,m_z+gcc.m_z);
        }

        GCC operator-(const GCC& gcc) const
        {
            return GCC(m_x-gcc.m_x,m_y-gcc.m_y,m_z-gcc.m_z);
        }

        GCC operator*(double scale) const
        {
            return GCC(m_x*scale,m_y*scale,m_z*scale);
        }

        GCC operator/(double scale) const
        {
            return GCC(m_x/scale,m_y/scale,m_z/scale);
        }

        GCC operator*(const GCC& gcc) const
        {
            return GCC(m_x*gcc.m_x,m_y*gcc.m_y,m_z*gcc.m_z);
        }

        GCC operator/(const GCC& gcc) const
        {
            return GCC(m_x/gcc.m_x,m_y/gcc.m_y,m_z/gcc.m_z);
        }

        GCC& operator+=(const GCC& gcc)
        {
            m_x+=gcc.m_x;
            m_y+=gcc.m_y;
            m_z+=gcc.m_z;
            return *this;
        }

        GCC& operator-=(const GCC& gcc)
        {
            m_x-=gcc.m_x;
            m_y-=gcc.m_y;
            m_z-=gcc.m_z;
            return *this;
        }

        double dot(const GCC& v) const
        {
            return m_x * v.m_x + m_y * v.m_y + m_z * v.m_z;
        }

        GCC cross(const GCC& v) const
        {
            return GCC(m_y * v.m_z - m_z * v.m_y, m_z * v.m_x - m_x * v.m_z, m_x * v.m_y - m_y * v.m_x);
        }

        double length() const
        {
            return sqrt(m_x * m_x + m_y * m_y + m_z * m_z);
        }

        double distance(const GCC& v) const
        {
            return sqrt((m_x - v.m_x) * (m_x - v.m_x) + (m_y - v.m_y) * (m_y - v.m_y) + (m_z - v.m_z) * (m_z - v.m_z));
        }


        GDC toGDC(bool isEllipsoid = true) const;

        CLASS_PARAMS_PUBLIC(double,m_x,x);
        CLASS_PARAMS_PUBLIC(double,m_y,y);
        CLASS_PARAMS_PUBLIC(double,m_z,z);
    };
    typedef std::vector<GCC> GCCVector;
}

#endif